// stk_para.h

#ifndef DODO_STK_PARA_H
#define DODO_STK_PARA_H
#include <string>
#include <cmath>
#include <stdexcept>
#include <quigon.h>

namespace quigon
{

// For convinience, Para's are struct, with everything public.
class STK_Para
{
public:
	STK_Para() {};
	STK_Para(const std::string& filename)
	{
		if (!load(filename))
		{
			func_err("STK_Para::(filename)", filename);
		}
	}

	bool load(const std::string& filename);
public:
	std::string lidar_name;
	size_t size; // how many bins in a line.
	double bin_size;
	double start_value; // start_value = - zero_meter_index * bin_size + 0.5 * bin_size

	double station_height;	// required for accuracy
	double station_lat;		// better have geo location info
	double station_lon;		//

	size_t zero_meter_index;  // index for first position IN FRONT of the lidar
	size_t first_usable_index;	// index for first position out of the BLIND AREA
	double lambda; // laser wave length, in nm, e.g. 523.0
	double rho_n; //0.0284 ;   //depolarization factor, actually 0.0284 is for 550nm. but I didn't find a preciser one...
	Link_Stuff<Time_Serie> lidar_ratio;
	Link_Stuff<Time_Serie> lidar_constant;
	Link_Stuff<Time_Serie> elev_angle;

	// For searching convinience, distanc_i uses Serie
	// Not adding height here, cause they change with sin_elev_angle;
	// height = distance * sin_elev_angle, this is simple.
	Lidar_Profile distance;
	Lidar_Cross_Ref distance_i;

	Link_Stuff<Lidar_Profile> overlap;
	Link_Stuff<Lidar_Profile> afterpulse;

	std::string data_path;
	std::string file_ext;
public:
	//function member
	//gona move them away ...
	double height(
	        size_t i,
	        boost::posix_time::ptime t = boost::posix_time::not_a_date_time
	) const
	{
		if (t.is_special())
			return distance[i] * sin(M_PI / 180.0 * elev_angle()()) + station_height;
		else
			return distance[i] * sin(M_PI / 180.0 * elev_angle()[t]) + station_height;
	}
	size_t height_i(
	        double h,
	        boost::posix_time::ptime t = boost::posix_time::not_a_date_time
	) const
	{
		if (t.is_special())
			return distance_i[(h - station_height) / sin(M_PI / 180.0 * elev_angle()())];
		else
			return distance_i[(h - station_height) / sin(M_PI / 180.0 * elev_angle()[t])];
	}
};


//STK_Para load_stk_para(const std::string& filename) ;
}

#endif

